2024-07-25


Typescript generics and indexed access types
I was writing a wrapper for creating SVG filter elements before I realized that I should just use the HTML elements instead (in Svelte that is).
I did learn something though, when you want to type something where the available parameters change depending on something (in my case a light type) you can use typescript generics and indexed access types.
Some light types:
export type LightTypes = {
  feDistantLight: FeDistantLightAttributes;
  fePointLight: FePointLightAttributes;
  feSpotLight: FeSpotLightAttributes;
};
Some example attributes:
export type FeDiffuseLightingAttributes = {
	in?: inType;
	diffuseConstant?: number;
	surfaceScale?: number;
	"lighting-color"?: string;
	result?: string;
};

export type FeDistantLightAttributes = {
	azimuth?: number;
	elevation?: number;
};
The function:
  feDiffuseLightingWithLight<K extends keyof LightTypes>(attrs: FeDiffuseLightingAttributes, type: K, lightAttrs: LightTypes[K]) {
    let elem = this.addElement("feDiffuseLighting", attrs) as SVGFilterElement;

    this.addElement(type, lightAttrs, elem);
    return this;
  }
This way when I call it with .feDiffuseLightingWithLight({ "lighting-color": "#4a7997", result: "textured" }, "feDistantLight", { azimuth: 90, elevation: 50 }) I can only see the azimuth and elevation properties within the object since I passed in "feDistantLight". Properties from other types of light will give a typescript error.
Go back to all posts